package org.gap.esupport;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.apache.commons.io.FileUtils;

@SuppressWarnings("serial")
public class FeatureSupport extends JFrame {
	public static final String MAIN_WINDOW = "mainWindow";
	public static final String FEATURE_LOCATION = "featureLocation";
	public static final String AVAILABLE_FEATURES = "availableFeatures";
	public static final String PERFORM_SEARCH = "performSearch";
	private JTextField startLocation;
	private JList availableFeatures;
	private JButton searchActivator;
	private JPanel canvas;
	
	public static void main(String... arguments) {
		FeatureSupport app = new FeatureSupport();
		app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		app.setSize(800, 450);
		app.setVisible(true);
	}

	public FeatureSupport() {
		this.setName(MAIN_WINDOW);
		this.setLayout(new BorderLayout());
		JPanel sidePanel = new JPanel(new BorderLayout());
		createLocateFeaturesInDirectory(sidePanel);
		createFeaturesFound(sidePanel);
		this.add(sidePanel, BorderLayout.WEST);
		createFeatureCanvas();
		
		searchActivator.addActionListener(thatSearchesForFeaturesIn(startLocation, availableFeatures));
	}

	private void createLocateFeaturesInDirectory(JPanel container) {
		startLocation = new JTextField();
		startLocation.setColumns(25);
		startLocation.setName(FEATURE_LOCATION);
		
		searchActivator = new JButton("Search");
		searchActivator.setName(PERFORM_SEARCH);
		JPanel panel = new JPanel(new FlowLayout());
		panel.add(startLocation);
		panel.add(searchActivator);
		
		container.add(panel, BorderLayout.NORTH);
	}
	
	private void createFeaturesFound(JPanel container) {
		availableFeatures = new JList(new String[0]);
		availableFeatures.setName(AVAILABLE_FEATURES);
		
		container.add(availableFeatures, BorderLayout.CENTER);
	}
	
	private void createFeatureCanvas() {
		canvas = new JPanel();
		canvas.setSize(400, 400);
		
		this.add(canvas, BorderLayout.CENTER);
	}

	private ActionListener thatSearchesForFeaturesIn(final JTextField startLocation, final JList availableFeatures) {
		return new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				canvas.removeAll();
				List<String> result = new ArrayList<String>();
				String location = startLocation.getText();
				File directory = new File(location);
				searchLocation(result, directory);
				DefaultListModel defaultListModel = new DefaultListModel();
				for (String each : result) {
					defaultListModel.addElement(each);
					JButton feature = new JButton(each);
					feature.setName(each);
					canvas.add(feature);
				}
				availableFeatures.setModel(defaultListModel);
			}

			private void searchLocation(List<String> result, File location) {
				if (location.isDirectory()) {
					String[] featureXmlList = location.list(ofFeatureXmlFiles());
					if (featureXmlList.length == 1) {
						String feature = nameOfFeature(location, featureXmlList);
						result.add(feature);
						return;
					}
				}
				for (File each : listDirectories(location.listFiles())) {
					searchLocation(result, each);
				}
			}

			private FilenameFilter ofFeatureXmlFiles() {
				return new FilenameFilter() {
					
					@Override
					public boolean accept(File dir, String name) {
						return "feature.xml".equals(name.toLowerCase());
					}
				};
			}
			
			private String nameOfFeature(File location, String[] featureXmlList) {
				File file = new File(location.getAbsolutePath() + File.separator + featureXmlList[0]);
				try {
					String text = FileUtils.readFileToString(file);
					int start = text.toLowerCase().indexOf("id=\"") + 4;
					int end = text.toLowerCase().indexOf("\"", start);
					return text.substring(start, end);
				} catch (IOException e) {
					e.printStackTrace();
				}
				return "";
			}

			private Collection<File> listDirectories(File[] listFiles) {
				List<File> directories = new ArrayList<File>();
				for (File each : listFiles) {
					if (each.isDirectory())
						directories.add(each);
				}
				return directories;
			}
		};
	}
}
